// 想要使用必须先引入 defineStore；
import { defineStore } from 'pinia';
import { TagView } from '@pinia/types/tagsView';

// 第二个参数是选项，对象里面有三个属性，相比于vuex 少了一个 mutations.
export const tagsViewPinia = defineStore({
  id: 'tagsView',
  state: () => {
    // 存放的就是模块的变量
    return {
      visitedViews: [],
      cachedViews: [],
    };
  },
  actions: {
    // 可以通过actions 方法，改变 state 里面的值。
    // 要观察作用域范围
    addVisitedView(view: TagView): void {
      if (this.visitedViews.some((v) => v.path === view.path)) return;
      this.visitedViews.push(
        Object.assign({}, view, {
          title: view.meta?.title || 'no-name',
        }),
      );
    },
    addCachedView(view: TagView): void {
      const viewName = view.name as string;
      if (!viewName) return;
      if (this.cachedViews.includes(viewName)) return;
      if (!view.meta?.noCache) {
        this.cachedViews.push(viewName);
      }
    },
    addView(view: TagView) {
      this.addVisitedView(view);
      this.addCachedView(view);
    },
    delVisitedView(view: TagView): Promise<TagView[]> {
      return new Promise((resolve) => {
        for (const [i, v] of this.visitedViews.entries()) {
          if (v.path === view.path) {
            this.visitedViews.splice(i, 1);
            break;
          }
        }
        resolve([...this.visitedViews]);
      });
    },
    delCachedView(view?: TagView): Promise<string[]> {
      let viewName = '';
      if (view) {
        viewName = view.name as string;
      }
      return new Promise((resolve) => {
        const index = this.cachedViews.indexOf(viewName);
        index > -1 && this.cachedViews.splice(index, 1);
        resolve([...this.cachedViews]);
      });
    },
    delView(view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> {
      return new Promise((resolve) => {
        this.delVisitedView(view);
        this.delCachedView(view);
        resolve({
          visitedViews: [...this.visitedViews],
          cachedViews: [...this.cachedViews],
        });
      });
    },
    delOthersVisitedViews(view: TagView): Promise<TagView[]> {
      return new Promise((resolve) => {
        this.visitedViews = this.visitedViews.filter((v) => {
          return v.meta?.affix || v.path === view.path;
        });
        resolve([...this.visitedViews]);
      });
    },
    delOthersCachedViews(view: TagView): Promise<string[]> {
      const viewName = view.name as string;
      return new Promise((resolve) => {
        const index = this.cachedViews.indexOf(viewName);
        if (index > -1) {
          this.cachedViews = this.cachedViews.slice(index, index + 1);
        } else {
          this.cachedViews = [];
        }
        resolve([...this.cachedViews]);
      });
    },
    delOthersViews(view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> {
      return new Promise((resolve) => {
        this.delOthersVisitedViews(view);
        this.delOthersCachedViews(view);
        resolve({
          visitedViews: [...this.visitedViews],
          cachedViews: [...this.cachedViews],
        });
      });
    },
    delAllVisitedViews(): Promise<TagView[]> {
      return new Promise((resolve) => {
        this.visitedViews = this.visitedViews.filter((tag) => tag.meta?.affix);
        resolve([...this.visitedViews]);
      });
    },
    delAllCachedViews(): Promise<string[]> {
      return new Promise((resolve) => {
        this.cachedViews = [];
        resolve([...this.cachedViews]);
      });
    },
    delAllViews(): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> {
      return new Promise((resolve) => {
        this.delAllVisitedViews();
        this.delAllCachedViews();
        resolve({
          visitedViews: [...this.visitedViews],
          cachedViews: [...this.cachedViews],
        });
      });
    },
    updateVisitedView(view: TagView): void {
      for (let v of this.visitedViews) {
        if (v.path === view.path) {
          v = Object.assign(v, view);
          break;
        }
      }
    },
    delRightTags(view: TagView): Promise<TagView[]> {
      return new Promise((resolve) => {
        const index = this.visitedViews.findIndex((v) => v.path === view.path);
        if (index === -1) {
          return;
        }
        this.visitedViews = this.visitedViews.filter((item, idx) => {
          if (idx <= index || (item.meta && item.meta.affix)) {
            return true;
          }
          const i = this.cachedViews.indexOf(item.name as string);
          if (i > -1) {
            this.cachedViews.splice(i, 1);
          }
          return false;
        });
        resolve([...this.visitedViews]);
      });
    },
    delLeftTags(view: TagView): Promise<TagView[]> {
      return new Promise((resolve) => {
        const index = this.visitedViews.findIndex((v) => v.path === view.path);
        if (index === -1) {
          return;
        }
        this.visitedViews = this.visitedViews.filter((item, idx) => {
          if (idx >= index || (item.meta && item.meta.affix)) {
            return true;
          }
          const i = this.cachedViews.indexOf(item.name as string);
          if (i > -1) {
            this.cachedViews.splice(i, 1);
          }
          return false;
        });
        resolve([...this.visitedViews]);
      });
    },
  },
  persist: {
    //  固化插件
    enabled: true, // 开启存储
    strategies: [
      // 指定存储的位置以及存储的变量都有哪些，该属性可以不写，
      //在不写的情况下，默认存储到 sessionStorage 里面,默认存储 state 里面的所有数据。
      { storage: localStorage, paths: ['dataBox'] },
    ],
  },
});

export default tagsViewPinia;
